<!--
 * @Author: Soulmate
 * @Date: 2023-10-17 09:06:27
 * @LastEditTime: 2023-10-19 15:53:46
 * @LastEditors: Soulmate
 * @Description: 
 * @FilePath: \ruoyi-ui-vue3\src\components\Map\GD\index.vue
 * 版权声明
-->
<template>
    <div class="map-gd" id="container" ref="map"></div>
</template>

<script setup lang="ts">
import AMapLoader from '@amap/amap-jsapi-loader';
import { createControlHtml } from '@/utils/map';

const props = defineProps({
    mapConfig: {
        type: Object,
        default: {},
    },
});

onMounted(() => {
    loadMap();
});

let map = null; // 地图
let polygonEditor = null; // 矢量编辑器
let polygons = null; //当前绘制的矢量
let isWhiteMapDom = ''; //是否正在绘制
let isPolylineEdit = false;
let polylines = []; //当前绘制的折线经纬度
let polylineIndex = 0;
let polylinesList = [[]]; //折线数组
let polylineHasMarkerList = []; //折线点位数组
let markerList = []; // 标记点数组
/**
 * 加载高德地图
 */
const loadMap = () => {
    (window as any)._AMapSecurityConfig = {
        securityJsCode: 'de6258863f3e2d6428f1a17c8c200312',
    };
    AMapLoader.load({
        key: '55c6b0260e16b20664b8b3f7e5a6b747', // 申请好的Web端开发者Key，首次调用 load 时必填
        version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
        plugins: [
            'AMap.ToolBar',
            'AMap.Scale',
            'AMap.HawkEye',
            'AMap.Polygon',
            'AMap.Polygon',
            'AMap.Polyline',
            'AMap.Map',
            'AMap.Marker',
            'AMap.Geolocation',
            'AMap.MapType',
            'AMap.PolygonEditor',
        ], // 需要使用的的插件列表，如比例尺'AMap.Scale'等
    }).then((AMap) => {
        initMap(props.mapConfig);
    });
};
/**
 * 初始化地图
 */
const initMap = (data) => {
    const map = new AMap.Map('container', {
        ...data,
    });
    map.addControl(
        new AMap.ToolBar({
            position: 'LT', //定位到左上角
            offset: [20, 80], //偏移量 x,y轴
        }),
    ); // 工具条控件;范围选择控件
    map.addControl(new AMap.Scale()); // 显示当前地图中心的比例尺
    map.addControl(new AMap.HawkEye()); // 显示缩略图
    map.addControl(new AMap.Geolocation()); // 定位当前位置
    map.addControl(new AMap.MapType()); // 实现默认图层与卫星图,实时交通图层之间切换

    // 初始化覆盖物
    initPolygons(map);

    // 新增折线
    // addPolyline(map);

    // 添加自定义控件
    addControls(map).then((res) => {
        listenerEvent(map);
    });
};
const addControls = () => {
    return new Promise((resolve, reject) => {
        createControlHtml(props.mapConfig.controls);
        resolve(true);
    });
};
/**监听事件 */
const listenerEvent = (map) => {
    map.on('click', function (e) {
        let { lat, lng } = e.lnglat;
        var _path = [lng, lat];
        if (isWhiteMapDom == 'createPolyline') {
            var marker = new AMap.Marker({
                map: map,
                position: _path,
                size: 10,
                icon: new AMap.Icon({
                    image: `http://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png`,
                    size: new AMap.Size(22, 28), //图标所处区域大小
                    imageSize: new AMap.Size(22, 28), //图标大小
                }),
                offset: new AMap.Pixel(-10, -23),
                autoRotation: true,
            });

            marker.on('dblclick', function (e) {
                let { lat, lng } = e.lnglat;
                if (polylines.filter((item) => item[0].toFixed(4) == lng.toFixed(4) && item[1].toFixed(4) == lat.toFixed(4)).length > 0) {
                    if (polylines.length > 2) {
                        marker.setMap(map);
                        polylines.push([lng, lat]);
                        if (polylines.length > 1) {
                            setPolyline(map);
                        }
                    }
                    polylineConfirmDom.children[0].click();
                }
            });
            marker.setMap(map);
            polylineHasMarkerList.push(marker);
            polylines.push(_path);
            if (polylines.length > 1) {
                setPolyline(map);
            }
        }

        if (isWhiteMapDom == 'createMarker') {
            var marker = new AMap.Marker({
                map: map,
                position: _path,
                size: 10,
                icon: new AMap.Icon({
                    image: `${new URL(`../../../assets/icons/svg/marker.svg`, import.meta.url).href}`,
                    size: new AMap.Size(22, 28), //图标所处区域大小
                    imageSize: new AMap.Size(30, 35), //图标大小
                }),
                offset: new AMap.Pixel(-10, -23),
                autoRotation: true,
            });
            marker.setMap(map);
            markerList.push(marker);
        }
    });

    // 监听绘制多边形tool
    let createPolygonDom = document.getElementById('createPolygon');
    let polygonConfirmDom = document.getElementById('polygonConfirm');
    createPolygonDom.addEventListener('click', function () {
        polygonEditor.close();
        polygonEditor.setTarget();
        polygonEditor.open();
        polygonConfirmDom.classList.add('active');
    });
    // 完成按钮
    polygonConfirmDom.children[0].addEventListener('click', function (e) {
        polygonEditor.close();
        polygonConfirmDom.classList.remove('active');
        e.stopPropagation();
    });
    // 重绘按钮
    polygonConfirmDom.children[1].addEventListener('click', function (e) {
        if (!!polygons) map.remove(polygons);
        polygonEditor.close();
        polygonEditor.setTarget();
        polygonEditor.open();
        polygons = null;
        e.stopPropagation();
    });
    // 绘制矢量图形
    polygonEditor.on('add', function (data) {
        var polygon = data.target;
        polygonEditor.addAdsorbPolygons(polygon);
        polygon.on('dblclick', () => {
            polygons = polygon;
            polygonEditor.setTarget(polygon);
            polygonEditor.open();
            polygonConfirmDom.classList.add('active');
        });
        polygons = polygon;
    });

    // 绘制折线覆盖物
    let createPolylineDom = document.getElementById('createPolyline');
    let polylineConfirmDom = document.getElementById('polylineConfirm');
    createPolylineDom.addEventListener('click', function () {
        isWhiteMapDom = 'createPolyline';
        polylineConfirmDom.classList.add('active');
    });
    // 完成按钮
    polylineConfirmDom.children[0].addEventListener('click', function (e) {
        if (!isPolylineEdit) {
            polylineIndex++;
        } else {
            polylineIndex = polylinesList.length;
        }
        polylines = [];
        isWhiteMapDom = '';
        polylineHasMarkerList.forEach((item) => map.remove(item));
        polylineHasMarkerList = [];
        polylineConfirmDom.classList.remove('active');
        isPolylineEdit = false;
        e.stopPropagation();
    });
    // 回退按钮
    polylineConfirmDom.children[1].addEventListener('click', function (e) {
        // isWhiteMapDom = '';
        polylinesList[polylineIndex].forEach((item) => map.remove(item));
        polylineHasMarkerList.forEach((item) => map.remove(item));
        // polylinesList.splice(polylineIndex, 1);
        delete polylinesList[polylineIndex];
        polylineHasMarkerList = [];
        polylines = [];
        if (isPolylineEdit) {
            isPolylineEdit = false;
            polylineConfirmDom.classList.remove('active');
        }
        e.stopPropagation();
    });

    // 绘制标记点位
    let createMarkerDom = document.getElementById('createMarker');
    let markerConfirmDom = document.getElementById('markerConfirm');
    createMarkerDom.addEventListener('click', function () {
        isWhiteMapDom = 'createMarker';
        markerConfirmDom.classList.add('active');
    });
    // 完成按钮
    markerConfirmDom.children[0].addEventListener('click', function (e) {
        isWhiteMapDom = '';
        markerConfirmDom.classList.remove('active');
        e.stopPropagation();
    });
    // 回退按钮
    markerConfirmDom.children[1].addEventListener('click', function (e) {
        markerList.forEach((item) => map.remove(item));
        isWhiteMapDom = '';
        markerConfirmDom.classList.remove('active');
        e.stopPropagation();
    });
};
/**
 * 折线覆盖物
 */
const setPolyline = (map) => {
    let polyline = new AMap.Polyline({
        path: polylines,
        isOutline: true,
        outlineColor: '#ffeeff',
        borderWeight: 3,
        strokeColor: '#3366FF',
        strokeOpacity: 1,
        strokeWeight: 2,
        // 折线样式还支持 'dashed'
        strokeStyle: 'solid',
        // strokeStyle是dashed时有效
        strokeDasharray: [10, 5],
        lineJoin: 'round',
        lineCap: 'round',
        zIndex: 50,
        extData: polylineIndex + 1,
    });
    polyline.setMap(map);
    if (!polylinesList[polylineIndex]) polylinesList[polylineIndex] = [];
    polylinesList[polylineIndex].push(polyline);
    polyline.on('dblclick', function (e) {
        polylines = [...e.target.$x[0]];
        // 初始化marker
        polylineHasMarkerList.forEach((item) => map.remove(item));
        polylineHasMarkerList = [];
        polylines.forEach((item) => {
            var marker = new AMap.Marker({
                map: map,
                position: [item[0], item[1]],
                size: 10,
                icon: new AMap.Icon({
                    image: `http://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png`,
                    size: new AMap.Size(22, 28), //图标所处区域大小
                    imageSize: new AMap.Size(22, 28), //图标大小
                }),
                offset: new AMap.Pixel(-10, -23),
                autoRotation: true,
            });
            marker.setMap(map);
            polylineHasMarkerList.push(marker);
        });

        document.getElementById('polylineConfirm').classList.add('active');
        isPolylineEdit = true;

        isWhiteMapDom = '';

        polylineIndex = polyline.getExtData() - 1;
    });
    // 缩放地图到合适的视野级别(以三环线为参考)
    map.setFitView([polyline]);
};
/**
 * 多边形覆盖物
 */
const initPolygons = (map) => {
    var path1 = [
        [116.475334, 39.997534],
        [116.476627, 39.998315],
        [116.478603, 39.99879],
        [116.478529, 40.000296],
        [116.475082, 40.000151],
        [116.473421, 39.998717],
    ];
    var path2 = [
        [116.474595, 40.001321],
        [116.473526, 39.999865],
        [116.476284, 40.000917],
    ];
    var polygon1 = new AMap.Polygon({
        path: path1,
    });
    var polygon2 = new AMap.Polygon({
        path: path2,
    });
    map.add([polygon1, polygon2]);
    map.setFitView();

    polygonEditor = new AMap.PolygonEditor(map);
    polygonEditor.addAdsorbPolygons([polygon1, polygon2]);
    polygon1.on('dblclick', () => {
        polygonEditor.setTarget(polygon1);
        polygonEditor.open();
    });
    polygon2.on('dblclick', () => {
        polygonEditor.setTarget(polygon2);
        polygonEditor.open();
    });
};
</script>

<style scoped lang="scss">
@import '@/assets/styles/variables.module.scss';

.map-gd {
    width: 100%;
    height: 100%;
    ::v-deep(.commonControl) {
        position: relative;
        border-top: 1px solid #eee;
        .commonControlConfirm {
            width: 90px;
            height: 30px;
            position: absolute;
            left: 35px;
            top: 0px;
            display: none;
            span {
                width: 40px;
                margin: 0px 2px;
                font-size: 12px;
                cursor: pointer;
                color: #fff;
                font-weight: 500;
                &:first-child {
                    background: #2196f3;
                }
                &:last-child {
                    background: #ff6060;
                }
                &:hover {
                    font-weight: 600;
                }
            }
            &.active {
                display: flex;
            }
        }
        &:hover {
            img {
                transform: scale(1.1);
            }
        }
    }
}
</style>
